package com.ai.wxy.spring.storm.test.hystrix.command;

import com.netflix.hystrix.*;
import lombok.extern.slf4j.Slf4j;

import java.util.Random;

/**
 * Histrix Command 参数配置测试
 *
 * @author 石头
 * @Date 2019/12/17
 * @Version 1.0
 **/
@Slf4j
public class HistrixCommandConf extends HystrixCommand<String>{
    private Random random = new Random(System.currentTimeMillis());
    private String name;
    public HistrixCommandConf(String name){
        super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("test_conf_group"))
                .andCommandKey(HystrixCommandKey.Factory.asKey("histrixCommandConf"))
                .andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey("histrixCommandConfPool"))
                // 线程池配置
                .andThreadPoolPropertiesDefaults(HystrixThreadPoolProperties.Setter()
                        .withCoreSize(5)
                        .withMaximumSize(20)
                        .withKeepAliveTimeMinutes(1)
                        .withMaxQueueSize(10)
                )
                .andCommandPropertiesDefaults(HystrixCommandProperties.Setter()
                        // 设置隔离方式，默认为Thread线程方式。
                        .withExecutionIsolationStrategy((HystrixCommandProperties.ExecutionIsolationStrategy.THREAD))
                        // 短路器设置
                        // 设置窗口期内的并发数，超过了会触发短路
                        .withCircuitBreakerRequestVolumeThreshold(10)
                        // 设置窗口期内异常百分比,超过了会触发短路,只有请求数据达到上面设置的值后才计算错误百分比。
                        .withCircuitBreakerErrorThresholdPercentage(80)
                        // 设置触发了短路后多长时间后进入holf-open半打开状态
                        .withCircuitBreakerSleepWindowInMilliseconds(3000)
                        // 接口超时时间
                        .withExecutionTimeoutInMilliseconds(310)
                        // 允许访问的最大并发量，超过这个最大并发量，请求直接被reject（隔离策略为信号量时有效）
                        .withFallbackIsolationSemaphoreMaxConcurrentRequests(15)

                )
        );

        this.name = name;
    }
    @Override
    protected String run() throws Exception {
        // 生成 [m,n] 的数字
        // int i1 = random.nextInt(n-m+1)+m;
        long sleep = random.nextInt(300 - 100 + 1) + 100;
//        if (sleep % 5 == 0){
//            throw new RuntimeException("调用失败");
//        }
        Thread.sleep(sleep);
        return name + "-" + random.nextLong();
    }

    @Override
    protected String getFallback() {
//        System.out.println("触发降级函数");
        return "降级数据";
    }
}
